#include "SeqList.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
/*
	Init_SeqList:初始化l指向的顺序表
	@l :指针。 指向要初始的顺序表
	@max_num :顺序表的最大元素个数
	返回值：
		成功 返回真
		失败 返回假
*/
bool Init_SeqList(struct SeqList*l, int max_num)
{
    l->data = malloc(sizeof(ElemType)*max_num);
    if(l->data == NULL)
        return false;
    l->capacity = max_num;
    l->num = 0;

    return true;
}
/*
    Create_SeqList:创建一个空的顺序表
    @max_num:最大元素个数

    返回值：
        成功：返回创建的顺序表结构体的地址
        失败：NULL
    注意：
        顺序表空间是开在堆空间中
*/
struct SeqList*Create_SeqList(int max_num)
{
    //创建顺序表
    struct SeqList *l = malloc(sizeof(*l));
    if(l == NULL)
        return NULL;
    
    //初始化
    if(!Init_SeqList(l, max_num))//初始化失败
    {
        free(l);
        l = NULL;
        return NULL;
    }

    return l;
}
/*
    Destroy_SeqList：销毁一个指向堆空间的顺序表
    @l :指针， 指向要销毁的顺序表

    返回值：
        无

    注释：
        该函数调用结束后，主调函数的指针将指向一个已释放的空间
    
*/
void Destroy_SeqList(struct SeqList* l)
{
    if(l == NULL)
        return;
    
    free(l->data);
    l->data = NULL;
    free(l);
    l = NULL;

}
/*
    Print_int_SeqList:打印l指向的顺序表
    @l : 指针，指向要打印的顺序表（仅限于整型数据的顺序表）

    返回值：
        无
*/
void Print_int_SeqList(struct SeqList*l)
{
    if(l == NULL)
        return;
   	printf("=================================\n");
    printf("capacity:%d  num:%d\n", l->capacity, l->num);
    for(int i = 0; i < l->num; i++)
    {
        printf("%d ",*(l->data+i));
    }
    printf("\n");
}
/*
	Insert_front:头插法在l指向的顺序表中插入一个元素d
    @l:顺序表
    @d: 插入的元素

	返回值：
		成功 true
		失败 false
*/
bool Insert_front(struct SeqList*l, ElemType d)
{
    if(l == NULL || l->num == l->capacity)
        return false;
    //空出第一个元素的位置
    for(int i = l->num; i >= 1; i--)
    {
        *(l->data+i) = *(l->data+i-1);
    }
    
    *l->data = d;// l->data[0] = d;
    l->num++;
    return true;
}

/*
	Insert_tail:尾插法 在l指向的顺序表中插入一个元素d
*/
bool Insert_tail(struct SeqList*l, ElemType d)
{
    if(l == NULL || l->num == l->capacity)
        return false;
    
    
    *(l->data+l->num) = d;// l->data[l->num] = d;
    l->num++;
    return true;
}
/*
    Insert_pos:在任意位置插入一个元素d
    @l :指向要插入元素的顺序表
    @pos : 下标 (从 0开始)
    @d :要插入的元素

    返回值：
        成功返回 true
        失败 ：false
*/
bool Insert_pos(struct SeqList*l, int pos, ElemType d)
{
    if(l == NULL || l->num == l->capacity || pos < 0 || pos > l->num)
        return false;
    //空出下标为 pos 的元素的位置
    for(int i = l->num; i >= pos+1; i--)
    {
        *(l->data+i) = *(l->data+i-1);
    }
  
    *(l->data+pos) = d;// l->data[pos] = d;
    l->num++;

    return true;
}

/*
	Delete_x;在一个l指向的顺序表中找到值为x的元素，将其删除，未找到则不删除
	如果有多个值为x的元素，则全部删除
	@l :指向要操作的顺序表
	@x:要删除的元素
	
	返回值：
		成功 true
		失败 false
*/
bool Delete_x(struct SeqList*l, ElemType d)
{
    if(l == NULL || l->num == 0)
        return false;
    int i = 0;
    while(1) 
    {
         //查找
        for( ; i < l->num; i++)
        {
            if(*(l->data+i) == d)
                break;
        }

        //删除
        if(i < l->num )
        {
            for(int j = i;j < l->num-1; j++)
            {
                *(l->data+j) = *(l->data+j+1);
            }
            l->num--;
        }
        else
        {
            break;
        }
    }

    return true;
}
/*
	Delete_x;在一个l指向的顺序表中找到值为x的元素，将其删除，未找到则不删除
	如果有多个值为x的元素，则全部删除
	@l :指向要操作的顺序表
	@x:要删除的元素
	
	返回值：
		成功 true
		失败 false
*/
bool Delete_x_1(struct SeqList*l, ElemType d)
{
    if(l == NULL || l->num == 0)
        return false;
    int i = 0;
     
    for( ; i < l->num; i++)
    {
        //查找
        if(*(l->data+i) == d)
        {
            //删除
            if(i < l->num )
            {
                for(int j = i;j < l->num-1; j++)
                {
                    *(l->data+j) = *(l->data+j+1);
                }
                l->num--;
                i--;
            }
        }
    }

    return true;
}

/*
	Update_x:在l指向的顺序表中找到值为x的元素，将其值修改为y,未找到则不修改
	@l :指向要操作的顺序表
	@x:要查找的元素
	@y：替换的元素
	返回值：
		成功 true
		失败 false
*/
bool Update_x(struct SeqList*l, ElemType x, ElemType y)
{
    if(l == NULL || l->num == 0)
        return false;
    int i = 0;
    for( ; i < l->num; i++)
    {
        //查找
        if(*(l->data+i) == x)
        {
            *(l->data+i) = y;
            return true;
        }
            

    }
    return false;
}
/*
	Get_Elem：在一个l指向的顺序表中，查找值为x的元素，找到 获取下标
	
	返回值：
		找到   >= 0 下标
		未找到 -1
*/
int Get_Elem(struct SeqList*l, ElemType x)
{
    if(l == NULL || l->num == 0)
        return -1;
    for(int i = 0; i < l->num;i++)
    {
        if(*(l->data+i) == x)
            return i;
    }
    
    return -1;
}

//=======================================
/*
	Get_index_Elem:在一个l指向的顺序表中，查找下标为index的元素，将其查找到的元素存储在x指向的空间
	
	返回值：
		找到 true  
		未找到 false  
*/
bool Get_index_Elem(struct SeqList*l, int index, ElemType* x)
{
    if(l == NULL || l->num == 0 || index < 0 || index >= l->num)
        return false;
    if(x)
    	*x = *(l->data+index);
    
    return true;
}
/*
    创建一个顺序表，并从键盘接收数字输入，将输入的正整数按从小到大的顺序插入顺序表，
    并在输入负整数的时候将其绝对值数据删除。
    每次输入后，将顺序表的内容打印到屏幕上， 0 表示结束。
*/
struct SeqList* Create_Input_SeqList(int capacity)
{
	struct SeqList*l = Create_SeqList(capacity);
    if(l == NULL)
        return NULL;
    
    while(1)
    {
        int d;
        scanf("%d", &d);
        if(d == 0)
            break;
        if(d > 0)//增加
        {
            //查找
            int i;
            for(i = 0; i < l->num; i++)
            {
                if(l->data[i] > d)
                    break;
            }
            if(i < l->num)//找到： i 就是要增加的元素下标
            {
                Insert_pos(l,i, d);
            }
            else//放最后
            {
                l->data[l->num] = d;
                l->num++;
            }
        }
        else//删除
        {
            Delete_x(l, -d);
        }

        //输出
        Print_int_SeqList(l);
    }

    return l;
}

